package com.calvin.study.rabbitmq.producer;

import javax.annotation.PostConstruct;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

//producer -> broker confirmCallback 消息未抵达服务器的确认回调
//exchange -> queue returnCallback   消息未抵达队列的确认回调
@Component
public class RabbitMqProducer implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

	@Autowired
	private RabbitTemplate rabbitTemplate;

	@PostConstruct
	public void initRabbitTemplate() {
		// 代表强制发送，即使exchange找不到routingkey对应的队列也会尝试，如果失败则会回调ReturnCallback
		rabbitTemplate.setMandatory(true);
		// 消息未抵达服务器的确认回调
		rabbitTemplate.setConfirmCallback(this);
		// 消息未抵达队列的确认回调
		rabbitTemplate.setReturnCallback(this);
	}

	@Override
	public void confirm(CorrelationData correlationData, boolean ack, String cause) {
		System.out.println("消息唯一的id correlationData: " + correlationData);
		String messageId = correlationData.getId();
		if (ack) {
			System.out.println("Producer投递消息[" + messageId + "]成功...");
		} else {
			// 失败则进行具体的后续操作:重试 或者补偿等手段
			System.out.println("Producer投递消息失败...");
		}
		if (cause != null) {
			System.out.println("ConfirmCallback Cause：" + cause);
		}
	}

	@Override
	public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
		System.err.println("Producer投递消息[" + message.getBody() + "]失败...");
		System.out.println("消息主体 message：" + message);
		System.out.println("回复的状态码：" + replyCode);
		System.out.println("回复的文本内容：" + replyText);
		System.out.println("exchange：" + exchange);
		System.out.println("routingKey：" + routingKey);
	}

	public void pushToExchange(String exchange, String routingKey, Object obj, String bizId) {
		// rabbitTemplate.setConfirmCallback(this);
		rabbitTemplate.convertAndSend(exchange, routingKey, obj, new CorrelationData(bizId));
	}

}
